using Nethereum.Hex.HexTypes;
using Nethereum.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

#if NET6_0_OR_GREATER
using System.Text.Json.Serialization;
#endif

namespace Nethereum.RPC.Eth.DTOs
{
    public class TransactionReceipt
    {
        /// <summary>
        /// DATA, 32 Bytes - hash of the transaction.
        /// </summary>
        [JsonProperty("transactionHash")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("transactionHash")]
#endif
        public string TransactionHash { get; set; }

        /// <summary>
        /// QUANTITY - integer of the transaction's index position in the block.
        /// </summary>
        [JsonProperty("transactionIndex")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("transactionIndex")]
#endif
        public HexBigInteger TransactionIndex { get; set; }

        /// <summary>
        /// DATA, 32 Bytes - hash of the block where this transaction was in.
        /// </summary>
        [JsonProperty("blockHash")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("blockHash")]
#endif
        public string BlockHash { get; set; }

        /// <summary>
        /// QUANTITY - block number where this transaction was in.
        /// </summary>
        [JsonProperty("blockNumber")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("blockNumber")]
#endif
        public HexBigInteger BlockNumber { get; set; }

        /// <summary>
        /// DATA, 20 Bytes - From address
        /// </summary>
        [JsonProperty("from")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("from")]
#endif
        public string From { get; set; }

        /// <summary>
        /// DATA, 20 Bytes - To address
        /// </summary>
        [JsonProperty("to")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("to")]
#endif
        public string To { get; set; }

        /// <summary>
        /// QUANTITY - The total amount of gas used when this transaction was executed in the block.
        /// </summary>
        [JsonProperty("cumulativeGasUsed")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("cumulativeGasUsed")]
#endif
        public HexBigInteger CumulativeGasUsed { get; set; }

        /// <summary>
        /// QUANTITY - The amount of gas used by this specific transaction alone.
        /// </summary>
        [JsonProperty("gasUsed")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("gasUsed")]
#endif
        public HexBigInteger GasUsed { get; set; }

        /// <summary>
        /// The actual value per gas deducted from the sender's account. Varies before and after EIP-1559.
        /// </summary>
        [JsonProperty("effectiveGasPrice")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("effectiveGasPrice")]
#endif
        public HexBigInteger EffectiveGasPrice { get; set; }

        /// <summary>
        /// DATA, 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise null.
        /// </summary>
        [JsonProperty("contractAddress")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("contractAddress")]
#endif
        public string ContractAddress { get; set; }

        /// <summary>
        /// QUANTITY / BOOLEAN - Transaction success (1) or failure (0)
        /// </summary>
        [JsonProperty("status")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("status")]
#endif
        public HexBigInteger Status { get; set; }

        /// <summary>
        /// logs: Array - Array of log objects generated by this transaction.
        /// </summary>
        [JsonProperty("logs")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("logs")]
        //[System.Text.Json.Serialization.JsonConverter(typeof(SystemTextJsonRawJArrayConverter))]
#endif
        public FilterLog[] Logs { get; set; }

        /// <summary>
        /// QUANTITY - The transaction type.
        /// </summary>
        [JsonProperty("type")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("type")]
#endif
        public HexBigInteger Type { get; set; }

        /// <summary>
        /// DATA, 256 Bytes - Bloom filter for log retrieval.
        /// </summary>
        [JsonProperty("logsBloom")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("logsBloom")]
#endif
        public string LogsBloom { get; set; }

        /// <summary>
        /// DATA, 32 Bytes - The post-transaction state root. Deprecated.
        /// </summary>
        [JsonProperty("root")]
#if NET6_0_OR_GREATER
        [JsonPropertyName("root")]
#endif
        public string Root { get; set; }

        public bool? HasErrors()
        {
            if (Status?.HexValue == null) return null;
            return Status.Value == 0;
        }

        public override bool Equals(object obj)
        {
            if (obj is TransactionReceipt val)
            {
                return TransactionHash == val.TransactionHash &&
                       TransactionIndex == val.TransactionIndex &&
                       BlockHash == val.BlockHash &&
                       BlockNumber == val.BlockNumber &&
                       From == val.From &&
                       To == val.To &&
                       CumulativeGasUsed == val.CumulativeGasUsed &&
                       GasUsed == val.GasUsed &&
                       ContractAddress.IsTheSameAddress(val.ContractAddress) &&
                       Status == val.Status &&
                       Type == val.Type &&
                       LogsBloom == val.LogsBloom;
            }

            return false;
        }
    }
}
